import 'package:dartkit/dartkit.dart';
import 'package:jaguar_jwt/jaguar_jwt.dart';

part 'args.dart';

/// 几个固态的token小工具
class TokenKit {
  /// 将一个特定的主体（比如用户的id信息）以及特定的有效时间结合[secret]融合在一起
  /// 通过一定的算法加密后，返回一个字符串token
  static String issue({required String subject, Duration? validTime}) {
    // 确定需要写入的信息
    final claim = JwtClaim(
      subject: subject,
      issuedAt: DateTime.now(),
      maxAge: validTime ?? Duration(days: 60), // 设置默认有效期为60天
    );

    // 生成token并返回
    final token = issueJwtHS256(claim, argSecret.value);
    return token;
  }

  /// 核销一个token，检查它的有效性，如果一切顺利，则返回它其中所包含的主体
  static String redeem(String token) {
    /// 有些token不一定符合规范，因此将它们格式化成标准格式
    if (token.startsWith("Bearer ")) {
      token = token.split("Bearer ")[1];
    }

    try {
      // 鉴定token并抽取信息，可能会抽取失败
      final JwtClaim claim = verifyJwtHS256Signature(token, argSecret.value);
      // 虽然和过期没有关系，但是这一条在实质上会检查令牌的过期状态
      claim.validate(issuer: null, audience: null);

      if (claim.subject == null) throw Bug("此token没有subject");
      // 将id返回
      return claim.subject!;
    } on JwtException catch (error) {
      // token过期
      if (error.message.contains("expired")) throw Bug("token已过期");
      // 其他情况不再寻找原因，统一回复失败
      throw Bug("token检验失败：$error");
    } catch (error) {
      throw Bug("token检验失败：$error");
    }
  }
}
